using MediatR;
using Microsoft.EntityFrameworkCore;
using WMS.Domain;
using WMS.ErrorCode;
using WMS.Infrasturcture.Interfaces;
using WMS.WebApiWrite.Application.Command;

namespace WMS.WebApiWrite.Application.Commandhandler
{
    /// <summary>
    /// 删除盘点信息命令处理器（使用事务进行逻辑删除）
    /// 同时逻辑删除盘点表、盘点明细表、上传附件表
    /// </summary>
    public class DeleteInventoryCommandHandler : IRequestHandler<DeleteInventoryCommand, ApiResult<bool>>
    {
        private readonly IBaseRepository<InventoryInfo> inventoryRepository;
        private readonly IBaseRepository<Inventory_check_details> detailsRepository;
        private readonly IBaseRepository<Uploadattachment> attachmentRepository;

        /// <summary>
        /// 构造函数，注入三个仓储
        /// </summary>
        public DeleteInventoryCommandHandler(
            IBaseRepository<InventoryInfo> inventoryRepository,
            IBaseRepository<Inventory_check_details> detailsRepository,
            IBaseRepository<Uploadattachment> attachmentRepository)
        {
            this.inventoryRepository = inventoryRepository;
            this.detailsRepository = detailsRepository;
            this.attachmentRepository = attachmentRepository;
        }

        /// <summary>
        /// 处理删除盘点信息命令（逻辑删除）
        /// </summary comprehensively>
        public async Task<ApiResult<bool>> Handle(DeleteInventoryCommand request, CancellationToken cancellationToken)
        {
            // 使用 ExecutionStrategy 包装事务（兼容 MySQL 重试策略）
            var strategy = inventoryRepository.DB.Database.CreateExecutionStrategy();

            return await strategy.ExecuteAsync(async () =>
            {
                // 在 ExecutionStrategy 中开启事务
                using var transaction = await inventoryRepository.DB.Database.BeginTransactionAsync(cancellationToken);

                try
                {
                    // ==================== 1. 查询盘点主表信息 ====================
                    var inventoryInfo = inventoryRepository.GetAll()
                        .Where(x => !x.IsDeleted)
                        .FirstOrDefault(x => x.InventoryId == request.InventoryId);

                    if (inventoryInfo == null)
                    {
                        await transaction.RollbackAsync(cancellationToken);
                        return new ApiResult<bool>
                        {
                            Code = ApiResultEnum.删除失败,
                            Message = "盘点信息不存在",
                            Data = false
                        };
                    }

                    string inventoryCode = inventoryInfo.InventoryCode;

                    // ==================== 2. 逻辑删除盘点主表 ====================
                    inventoryInfo.IsDeleted = true;
                    inventoryInfo.DeleteName = request.OperatorName;
                    inventoryInfo.DeleteTime = DateTime.Now;

                    await inventoryRepository.UpdateAsync(inventoryInfo);

                    // ==================== 3. 逻辑删除盘点明细表（通过盘点编号关联删除）====================
                    // 注意：Inventory_check_details 不继承 Audit，没有 IsDeleted 字段
                    // 如果需要逻辑删除明细表，可以考虑物理删除（因为明细表通常需要随主表一起删除）
                    // 或者为明细表添加 IsDeleted 字段
                    // 这里采用物理删除明细表的方案（因为明细表没有逻辑删除字段）
                    var detailsList = detailsRepository.GetAll()
                        .Where(x => x.InventoryCode == inventoryCode)
                        .ToList();

                    if (detailsList.Any())
                    {
                        await detailsRepository.DeleteRange(detailsList);
                    }

                    // ==================== 4. 逻辑删除上传附件表 ====================
                    var attachmentsList = attachmentRepository.GetAll()
                        .Where(x => x.InventoryCode == inventoryCode && !x.IsDeleted)
                        .ToList();

                    if (attachmentsList.Any())
                    {
                        // 批量逻辑删除附件表
                        foreach (var attachment in attachmentsList)
                        {
                            attachment.IsDeleted = true;
                            attachment.DeleteName = request.OperatorName;
                            attachment.DeleteTime = DateTime.Now;
                            await attachmentRepository.UpdateAsync(attachment);
                        }
                    }

                    // 提交事务
                    await transaction.CommitAsync(cancellationToken);

                    return new ApiResult<bool>
                    {
                        Code = ApiResultEnum.删除成功,
                        Message = $"删除盘点信息成功，盘点编号：{inventoryCode}，已删除明细 {detailsList.Count} 条，附件 {attachmentsList.Count} 个",
                        Data = true
                    };
                }
                catch (Exception ex)
                {
                    // 回滚事务
                    await transaction.RollbackAsync(cancellationToken);

                    return new ApiResult<bool>
                    {
                        Code = ApiResultEnum.删除失败,
                        Message = $"删除盘点信息异常：{ex.Message}",
                        Data = false
                    };
                }
            });
        }
    }
}

